#define AUTH_FILE_PATH "./data/app/cn.hdustea.quinplugin/authData.json"  //使用前记得修改权限文件的位置
#define MAIN_GROUP_ID 628669530  //使用前记得修改主群群号
#include "PrivilegePlugin.hpp"
namespace privilege
{
    using namespace std;
	using json = nlohmann::json;
	namespace database
	{
		void readAuthData(json& authDataJson)
        {
            ifstream authDataInStream(AUTH_FILE_PATH);
            ostringstream tempSS;
            tempSS << authDataInStream.rdbuf();
            string authDataString = tempSS.str();
            authDataJson = json::parse(authDataString);
        }
        void saveAuthData(json authDataJson)
        {
            ofstream authDataOutStream(AUTH_FILE_PATH);
            authDataOutStream << authDataJson.dump(4);
        }
        void syncAuthData(json& authDataJson)
        {
            readAuthData(authDataJson);
            unsigned int currentGroupCounts = authDataJson["group_list"].size();

            vector<cq::Group> joinedGroups = cq::api::get_group_list();

            //cq::logging::debug(u8"Privilege", u8"joined groups: " + to_string(joinedGroups.size()));
            //cq::logging::debug(u8"Privilege", u8"data groups: " + to_string(authDataJson["group_list"].size()));
            
            if(joinedGroups.size() > currentGroupCounts)
            {
                cq::logging::debug(u8"Privilege", u8"鉴权数据库群数量小于实际，开始更新数据库……");
                for (unsigned int i = 0; i < joinedGroups.size(); i++)
                {
                    bool found = false;
                    for (unsigned int j = 0; j < currentGroupCounts; j++)
                    {
                        if(authDataJson["group_list"][j]["group_id"] == joinedGroups[i].group_id)
                        {
                            found = true;
                            break;
                        }
                    }
                    if(!found)
                    {
                        authDataJson["group_list"][currentGroupCounts]["group_id"] = joinedGroups[i].group_id;
                        authDataJson["group_list"][currentGroupCounts]["group_name"] = joinedGroups[i].group_name;
                        authDataJson["group_list"][currentGroupCounts]["member_count"] = 0;
                        authDataJson["group_list"][currentGroupCounts]["member_list"] = json::array();
                        currentGroupCounts++;
                        //cq::logging::debug(u8"Privilege", u8"auth data: " + authDataJson.dump(4));
                    }
                }
                privilege::database::saveAuthData(authDataJson);
            }
            else if(joinedGroups.size() < currentGroupCounts)
            {
                cq::logging::debug(u8"Privilege", u8"鉴权数据库群数量大于实际，开始更新数据库……");
                for (unsigned int i = 0; i < currentGroupCounts; i++)
                {
                    bool found = false;
                    for (unsigned int j = 0; j < joinedGroups.size(); j++)
                    {
                        if(authDataJson["group_list"][i]["group_id"] == joinedGroups[j].group_id)
                        {
                            found = true;
                            break;
                        }
                    }
                    if(!found)
                    {
                        vector<json> tempJsonVec;
                        for (unsigned int j = 0; j < currentGroupCounts; j++)
                        {
                            if(j == i)
                            {
                                continue;
                            }
                            tempJsonVec.push_back(authDataJson["group_list"][j]);
                        }
                        nlohmann::json tempVectorJson(tempJsonVec);
                        authDataJson["group_list"] = tempVectorJson;
                        currentGroupCounts--;
                        //cq::logging::debug(u8"Privilege", u8"auth data: " + authDataJson.dump(4));
                    }
                }
                saveAuthData(authDataJson);
            }
            syncMemberData(authDataJson);
        }
        void syncMemberData(json& authDataJson)
        {
            vector<cq::Group> joinedGroups = cq::api::get_group_list();
            for (unsigned int i = 0; i < authDataJson["group_list"].size(); i++)
            {
                unsigned int tempMemberCount = (cq::api::get_group_info(authDataJson["group_list"][i]["group_id"])).member_count;
                if(authDataJson["group_list"][i]["member_count"] < tempMemberCount)
                {
                    cq::logging::debug(u8"Privilege", u8"群：" + to_string(authDataJson["group_list"][i]["group_id"]) + "成员数据小于实际，正在更新");

                    unsigned int currentMemberCount = authDataJson["group_list"][i]["member_count"];

                    vector<cq::GroupMember> tempMemberVec = cq::api::get_group_member_list(authDataJson["group_list"][i]["group_id"]);

                    for (unsigned int j = 0; j < tempMemberCount; j++)
                    {
                        bool found = false;
                        for (unsigned int k = 0; k < currentMemberCount; k++)
                        {
                            if(authDataJson["group_list"][i]["member_list"][k]["user_id"] == tempMemberVec[j].user_id)
                            {
                                found = true;
                                break;
                            }
                        }
                        if(!found)
                        {
                            authDataJson["group_list"][i]["member_list"][currentMemberCount]["user_id"] = tempMemberVec[j].user_id;
                            authDataJson["group_list"][i]["member_list"][currentMemberCount]["nickname"] = tempMemberVec[j].nickname;
                            authDataJson["group_list"][i]["member_list"][currentMemberCount]["auth_level"] = 3;
                            currentMemberCount++;
                            //cq::logging::debug(u8"Privilege", u8"auth data: " + authDataJson.dump(4));
                        }
                    }
                    authDataJson["group_list"][i]["member_count"] = tempMemberCount;
                }
                else if(authDataJson["group_list"][i]["member_count"] > tempMemberCount)
                {
                    cq::logging::debug(u8"Privilege", u8"群：" + to_string(authDataJson["group_list"][i]["group_id"]) + "成员数据大于实际，正在更新");

                    unsigned int currentMemberCount = authDataJson["group_list"][i]["member_count"];

                    vector<cq::GroupMember> tempMemberVec = cq::api::get_group_member_list(authDataJson["group_list"][i]["group_id"]);

                    for (unsigned int j = 0; j < currentMemberCount; j++)
                    {
                        bool found = false;
                        for (unsigned int k = 0; k < tempMemberCount; k++)
                        {
                            if(authDataJson["group_list"][i]["member_list"][j]["user_id"] == tempMemberVec[k].user_id)
                            {
                                found = true;
                                break;
                            }
                        }
                        if(!found)
                        {
                            vector<json> tempJsonVec;
                            for (unsigned int k = 0; k < currentMemberCount; k++)
                            {
                                if(k == j)
                                {
                                    continue;
                                }
                                tempJsonVec.push_back(authDataJson["group_list"][i]["member_list"][k]);
                            }
                            json tempVectorJson(tempJsonVec);
                            authDataJson["group_list"][i]["member_list"] = tempVectorJson;
                            currentMemberCount--;
                            //cq::logging::debug(u8"Privilege", u8"auth data: " + authDataJson.dump(4));
                        }
                    }
                    authDataJson["group_list"][i]["member_count"] = tempMemberCount;
                }
                
            }
            saveAuthData(authDataJson);
        }

        bool checkPermission(json& authDataJson, int64_t group_id, int64_t user_id, int permission_level)
        {
            string errorString;
            bool group_found = false;
            for (unsigned int i = 0; i < authDataJson["group_list"].size(); i++)
            {
                if(authDataJson["group_list"][i]["group_id"] == group_id)
                {
                    group_found = true;
                    bool user_found = false;
                    for (unsigned int j = 0; j < authDataJson["group_list"][i]["member_list"].size(); j++)
                    {
                        if(authDataJson["group_list"][i]["member_list"][j]["user_id"] == user_id)
                        {
                            user_found = true;
                            if(authDataJson["group_list"][i]["member_list"][j]["auth_level"] >= permission_level)
                            {
                                return true;
                            }
                            else
                            {
                                return false;
                            }   
                        }
                    }
                    if(!user_found)
                    {
                        cq::logging::debug(u8"Privilege", u8"群成员发生变动，开始更新数据库……");
                        syncMemberData(authDataJson);
                        errorString = "UPDATING_MEMBER_DATA";
                        throw errorString;
                    }
                }
            }
            if(!group_found)
            {
                cq::logging::debug(u8"Privilege", u8"群发生变动，开始更新数据库……");
                syncAuthData(authDataJson);
                errorString = "UPDATING_GROUP_DATA";
                throw errorString;
            }
        }
        int getPermission(json& authDataJson, int64_t group_id, int64_t user_id)
        {
            string errorString;
            bool group_found = false;
            for (unsigned int i = 0; i < authDataJson["group_list"].size(); i++)
            {
                if(authDataJson["group_list"][i]["group_id"] == group_id)
                {
                    group_found = true;
                    bool user_found = false;
                    for (unsigned int j = 0; j < authDataJson["group_list"][i]["member_list"].size(); j++)
                    {
                        if(authDataJson["group_list"][i]["member_list"][j]["user_id"] == user_id)
                        {
                            user_found = true;
                            return authDataJson["group_list"][i]["member_list"][j]["auth_level"]; 
                        }
                    }
                    if(!user_found)
                    {
                        cq::logging::debug(u8"Privilege", u8"群成员发生变动，开始更新数据库……");
                        syncMemberData(authDataJson);
                        errorString = "UPDATING_MEMBER_DATA";
                        throw errorString;
                    }
                }
            }
            if(!group_found)
            {
                cq::logging::debug(u8"Privilege", u8"群发生变动，开始更新数据库……");
                syncAuthData(authDataJson);
                errorString = "UPDATING_GROUP_DATA";
                throw errorString;
            }
        }
        void setPermission(json& authDataJson, int64_t group_id, int64_t user_id, int64_t admin_id, int auth_level)
        {
            string errorString;
            if(admin_id == user_id)
            {
                errorString = "SELF_EDITING_DENIED";
                throw errorString;
            }
            if(!checkPermission(authDataJson, group_id, admin_id, 70))
            {
                errorString = "NOT_AN_ADMIN";
                throw errorString;
            }
            cq::logging::debug(u8"Privilege", u8"auth user_id: " + to_string(user_id));
            bool group_found = false;
            for (unsigned int i = 0; i < authDataJson["group_list"].size(); i++)
            {
                if(authDataJson["group_list"][i]["group_id"] == group_id)
                {
                    group_found = true;
                    bool user_found = false;
                    for (unsigned int j = 0; j < authDataJson["group_list"][i]["member_list"].size(); j++)
                    {
                        if(authDataJson["group_list"][i]["member_list"][j]["user_id"] == user_id)
                        {
                            user_found = true;
                            authDataJson["group_list"][i]["member_list"][j]["auth_level"] = auth_level;
                            saveAuthData(authDataJson);
                            break;
                        }
                    }
                    if(!user_found)
                    {
                        cq::logging::debug(u8"Privilege", u8"群成员发生变动，开始更新数据库……");
                        syncMemberData(authDataJson);
                        errorString = "UPDATING_MEMBER_DATA";
                        throw errorString;
                    }
                }
            }
            if(!group_found)
            {
                cq::logging::debug(u8"Privilege", u8"群发生变动，开始更新数据库……");
                syncAuthData(authDataJson);
                errorString = "UPDATING_GROUP_DATA";
                throw errorString;
            }
        }

	}
	namespace core
	{
		string quotation_marks_remover(string rawString)
        {
            return rawString.substr(1,rawString.length()-2);
        }
	}
}